package com.whcoding.test.common;

import org.apache.commons.lang3.StringUtils;

import java.awt.geom.Point2D;

/**
 * @author whcoding
 * @version 1.0.0
 * @ClassName DistanceUtil
 * @Description 计算两坐标之间距离
 * @Date 2020/8/24 14:38
 */
public final class DistanceUtil {

    /**
     * 地球半径,单位 km
     */
    private static final double EARTH_RADIUS = 6378.137;

    /**
     * 根据经纬度，计算两点间的距离
     *
     * @param longitude1 第一个点的经度
     * @param latitude1  第一个点的纬度
     * @param longitude2 第二个点的经度
     * @param latitude2  第二个点的纬度
     * @return 返回距离 单位千米
     */
    public static double getDistance(String longitude1, String latitude1, String longitude2, String latitude2) {
        if (StringUtils.isBlank(longitude1) || StringUtils.isBlank(latitude1) || StringUtils.isBlank(longitude2) || StringUtils.isBlank(latitude2)) {
            return 0;
        }
        // 相同的经纬度
        if (longitude1.equals(longitude2) && latitude1.equals(latitude2)) {
            return 0;
        }
        return getDistance(Double.valueOf(longitude1), Double.valueOf(latitude1), Double.valueOf(longitude2), Double.valueOf(latitude2));
    }


    /**
     * 根据经纬度，计算两点间的距离
     *
     * @param longitude1 第一个点的经度
     * @param latitude1  第一个点的纬度
     * @param longitude2 第二个点的经度
     * @param latitude2  第二个点的纬度
     * @return 返回距离 单位千米
     */
    public static double getDistance(double longitude1, double latitude1, double longitude2, double latitude2) {
        Point2D pointDD = new Point2D.Double(longitude1, latitude1);
        Point2D pointXD = new Point2D.Double(longitude2, latitude2);
        return getDistance(pointDD, pointXD);
    }


    /**
     * 通过AB点经纬度获取距离
     *
     * @param pointA A点(经，纬)
     * @param pointB B点(经，纬)
     * @return 距离(单位 ： 米)
     */
    public static double getDistance(Point2D pointA, Point2D pointB) {
        // 经纬度（角度）转弧度。弧度用作参数，以调用Math.cos和Math.sin
        double radiansAX = Math.toRadians(pointA.getX()); // A经弧度
        double radiansAY = Math.toRadians(pointA.getY()); // A纬弧度
        double radiansBX = Math.toRadians(pointB.getX()); // B经弧度
        double radiansBY = Math.toRadians(pointB.getY()); // B纬弧度

        // cosβ1cosβ2cos（α1-α2）+sinβ1sinβ2
        double cos = Math.cos(radiansAY) * Math.cos(radiansBY) * Math.cos(radiansAX - radiansBX)
                + Math.sin(radiansAY) * Math.sin(radiansBY);
        double acos = Math.acos(cos); // 反余弦值
        return EARTH_RADIUS * acos; // 最终结果
    }

}
